package cn.tedu.mall.seckill.controller;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.JsonResult;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.pojo.seckill.dto.SeckillOrderAddDTO;
import cn.tedu.mall.pojo.seckill.vo.SeckillCommitVO;
import cn.tedu.mall.seckill.exception.SeckillBlockHandler;
import cn.tedu.mall.seckill.exception.SeckillFallbackHandler;
import cn.tedu.mall.seckill.service.ISeckillService;
import cn.tedu.mall.seckill.utils.SeckillCacheUtils;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/seckill")
@Api(tags = "提交秒杀订单")
public class SeckillController {
    @Autowired
    private ISeckillService seckillService;
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/{randCode}")
    @ApiOperation("随机码验证并提交秒杀订单")
    @ApiImplicitParam(value = "随机码",name = "randCode",dataType = "string")
    @PreAuthorize("hasRole('user')")
    //降级和流控
    @SentinelResource(value = "seckill",
    blockHandlerClass = SeckillBlockHandler.class,blockHandler = "seckillBlock",
    fallbackClass = SeckillFallbackHandler.class,fallback = "seckillFallback")
    public JsonResult<SeckillCommitVO> commitSeckill(@PathVariable String randCode,
                                                     SeckillOrderAddDTO seckillOrderAddDTO){
        //获取spuId
        Long spuId = seckillOrderAddDTO.getSpuId();
        //获取key
        String randCodeKey = SeckillCacheUtils.getRandCodeKey(spuId);
        //判断redis中是否包含这个key
        if(redisTemplate.hasKey(randCodeKey)){
            //获取随机码
           String redisRandCode =  redisTemplate.boundValueOps(randCodeKey).get()+"";
           //判断redis中是否有信息丢失
            if(redisRandCode==null)
                throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"服务器内部异常，请联系客服");
            //判断redis中随机码和前端传递的随机码是否一致
            if(!redisRandCode.equals(randCode))
                //不一致抛出异常
                throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"没有指定的商品");
            //执行购买操作
            SeckillCommitVO seckillCommitVO = seckillService.commitSeckill(seckillOrderAddDTO);
            return JsonResult.ok(seckillCommitVO);
        }else{
            //没有key，直接抛出异常
            throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"没有该商品");
        }
    }

}
